1 using System.Collections.Generic;
2 using ProceduralToolkit.Examples.UI;
3 using UnityEngine;
4 using UnityEngine.UI;
5
6 namespace ProceduralToolkit.Examples
7 {
8 public class CellularAutomatonConfigurator : ConfiguratorBase
9 {
10 public RectTransform leftPanel;
11 public ToggleGroup toggleGroup;
12 public RawImage image;
13 [Space]
14 public CellularAutomaton.Config config = new CellularAutomaton.Config();
15
16 private enum RulesetName
17 {
18 Life,
19 Mazectric,
20 Coral,
21 WalledCities,
22 Coagulations,
23 Anneal,
24 Majority,
25 }
26
27 private Color[] pixels;
28 private Texture2D texture;
29 private CellularAutomaton automaton;
30 private Color deadColor;
31 private Color aliveColor;
32 private TextControl header;
33
34 private Dictionary<RulesetName, Ruleset> nameToRuleset = new Dictionary<RulesetName, Ruleset>
35 {
36 {RulesetName.Life, Ruleset.life},
37 {RulesetName.Mazectric, Ruleset.mazectric},
38 {RulesetName.Coral, Ruleset.coral},
39 {RulesetName.WalledCities, Ruleset.walledCities},
40 {RulesetName.Coagulations, Ruleset.coagulations},
41 {RulesetName.Anneal, Ruleset.anneal},
42 {RulesetName.Majority, Ruleset.majority},
43 };
44
45 private void Awake()
46 {
47 pixels = new Color[config.width*config.height];
48 texture = new Texture2D(config.width, config.height, TextureFormat.ARGB32, false, true)
49 {
50 filterMode = FilterMode.Point
51 };
52 texture.Clear(Color.clear);
53 texture.Apply();
54 image.texture = texture;
55
56 header = InstantiateControl<TextControl>(leftPanel);
57 header.transform.SetAsFirstSibling();
58
59 var currentRulesetName = RulesetName.Life;
60 SelectRuleset(currentRulesetName);
61
62 InstantiateToggle(RulesetName.Life, currentRulesetName);
63 InstantiateToggle(RulesetName.Mazectric, currentRulesetName);
64 InstantiateToggle(RulesetName.Coral, currentRulesetName);
65 InstantiateToggle(RulesetName.WalledCities, currentRulesetName);
66 InstantiateToggle(RulesetName.Coagulations, currentRulesetName);
67 InstantiateToggle(RulesetName.Anneal, currentRulesetName);
68 InstantiateToggle(RulesetName.Majority, currentRulesetName);
69
70 InstantiateControl<SliderControl>(leftPanel).Initialize("Start noise", 0, 1, config.startNoise, value =>
71 {
72 config.startNoise = value;
73 Generate();
74 });
75
76 InstantiateControl<ToggleControl>(leftPanel).Initialize("Alive borders", config.aliveBorders, value =>
77 {
78 config.aliveBorders = value;
79 Generate();
80 });
81
82 InstantiateControl<ButtonControl>(leftPanel).Initialize("Generate", Generate);
83
84 Generate();
85 SetupSkyboxAndPalette();
86 }
87
88 private void Update()
89 {
90 automaton.Simulate();
91 DrawCells();
92 UpdateSkybox();
93 }
94
95 private void SelectRuleset(RulesetName rulesetName)
96 {
97 config.ruleset = nameToRuleset[rulesetName];
98
99 header.Initialize("Rulestring: " + config.ruleset);
100 }
101
102 private void Generate()
103 {
104 automaton = new CellularAutomaton(config);
105
106 GeneratePalette();
107
108 deadColor = GetMainColorHSV().WithSV(0.3f, 0.2f).ToColor();
109 aliveColor = GetMainColorHSV().ToColor();
110 }
111
112 private void DrawCells()
113 {
114 for (int x = 0; x < config.width; x++)
115 {
116 for (int y = 0; y < config.height; y++)
117 {
118 if (automaton.cells[x, y] == CellState.Alive)
119 {
120 pixels[y*config.width + x] = aliveColor;
121 }
122 else
123 {
124 pixels[y*config.width + x] = deadColor;
125 }
126 }
127 }
128
129 texture.SetPixels(pixels);
130 texture.Apply();
131 }
132
133 private void InstantiateToggle(RulesetName rulesetName, RulesetName selectedRulesetName)
134 {
135 var toggle = InstantiateControl<ToggleControl>(toggleGroup.transform);
136 toggle.Initialize(
137 header: rulesetName.ToString(),
138 value: rulesetName == selectedRulesetName,
139 onValueChanged: isOn =>
140 {
141 if (isOn)
142 {
143 SelectRuleset(rulesetName);
144 Generate();
145 }
146 },
147 toggleGroup: toggleGroup);
148 }
149 }
150 }